class Request {
	defaults = {
		baseURL: '',
		method: 'GET',
		data: null,
		url: '',
		header: {
			'Content-type': 'application/json' //数据交互格式
		},
		timeout: 3000,
		isLoading: true // 是否使用默认loading效果
	}

	// 拦截器对象
	interceptors = {
		request: (config) => {
			return config
		},

		response: (response) => {

			return response
		}
	}

	// 数组队列，初始值为空数组，用于储存请求队列，请求标识
	queue = []

	// 用于创建初始化类的属性和方法
	constructor(params = {}) {
		this.defaults = Object.assign({}, this.defaults, params)
	}

	request(options) {
		// 若有新请求，清除上一次定时器
		this.timerId && clearTimeout(this.timerId)

		options.url = this.defaults.baseURL + options.url
		options = Object.assign({}, this.defaults, options)

		if (options.isLoading && options.method !== 'UPLOAD') {
			// 判断queue队列是否为空，为空显示loading
			// 不为空，不显示loading，即不调用  uni.showLoading({})
			this.queue.length == 0 && uni.showLoading({})
			// 随后立即向 queue 队列添加标识请求
			// 每一个标识代表一个请求，标识是自定义的
			this.queue.push('request')
		}

		// 发请求前，调用请求拦截器
		options = this.interceptors.request(options)

		return new Promise((resolve, reject) => {
			if (options.method === 'UPLOAD') {
				uni.uploadFile({
					...options,
					success: (res) => {
						res.data = JSON.parse(res.data)
						const mergeRes = Object.assign({}, res, {
							config: options,
							isSuccess: true,
						})

						resolve(this.interceptors.response(mergeRes))
					},
					fail: (err) => {
						const mergeErr = Object.assign({}, err, {
							config: options,
							isSuccess: false,
						})

						reject(this.interceptors.response(mergeErr))
					}
				})
			} else {
				uni.request({
					...options,
					success: (res) => {
						// 在给响应拦截器参数时，需要将请求参数一起传递
						// 方便代码调式和其他逻辑处理，需要先合并参数
						// 然后将合并的参数传递给响应拦截器
						let mergeRres = Object.assign({}, res, {
							config: options,
							isSuccess: true
						})

						resolve(this.interceptors.response(mergeRres))
					},
					fail: (err) => {
						// 不管成功还失败响应，都会调用响应拦截器
						let mergeErr = Object.assign({}, err, {
							config: options,
							isSuccess: false
						})

						reject(this.interceptors.response(mergeErr))
					},
					complete: () => {
						if (options.isLoading) {
							// 每个请求结束后，都会执行 complete
							// 每次从 queue 队列中删除一个标识
							this.queue.pop()

							// 我觉得push的作用是，在没完全请求完之前始终留一个
							// 若是不push万一在请求中走了 113 行呢？！
							this.queue.length == 0 && this.queue.push('request')

							this.timerId = setTimeout(() => {
								this.queue.pop()

								// 删除标识后，判断目前 queue 是否为空
								// 为空，表示并发请求完成了，即隐藏 loading
								this.queue.length == 0 && uni.hideLoading()

								clearTimeout(this.timerId)
							}, 100)
						}

					}
				})

			}
		})
	}

	get(url, data = {}, config = {}) {
		return this.request(Object.assign({ url, data, method: 'GET' }, config))
	}

	post(url, data = {}, config = {}) {
		return this.request(Object.assign({ url, data, method: 'POST' }, config))
	}

	delete(url, data = {}, config = {}) {
		return this.request(Object.assign({ url, data, method: 'DELETE' }, config))
	}

	put(url, data = {}, config = {}) {
		return this.request(Object.assign({ url, data, method: 'PUT' }, config))
	}

	all(...params) {
		return Promise.all(params)
	}

	upload(url, filePath, name = 'file', config = {}) {
		return this.request(Object.assign({ url, filePath, name, method: 'UPLOAD' }, config))
	}
}

export default Request